package rmioverlay.server;

import java.rmi.*;
import java.rmi.registry.*;
import java.rmi.server.UnicastRemoteObject;
import java.net.BindException;
import java.net.MalformedURLException;

public class Server {
	/**
	 * The default port to be bound at server startup.
	 */
	public static final int DEFAULT_PORT = 1099;
	
	/**
	 * The reference of the server application.
	 */
	private ServerApp app;
	
	/**
	 * The reference of the RMI registry. 
	 */
	private Registry reg;
	
	/**
	 * Instantiates a server which will run the given server application
	 * @param app The application to be run.
	 */
	public <T extends ServerApp> Server(T app) {
		//Stores the ServerApp reference
		this.app = app;
	}
	
	/**
	 * Starts the server and server application on given port
	 * @param port The port to which the server will be bound
	 * @throws MalformedURLException if the AppName is not a correct URL
	 * @throws BindException if the port is already in use
	 */
	public void start(int port)
			throws RemoteException, MalformedURLException {
			//Creates RMI registry on given port
			this.reg = LocateRegistry.createRegistry(port);
			
			//Binds ServerApp object in the registry
			Naming.rebind(app.getClass().getSimpleName(), app);
	}
	
	/**
	 * Starts the server and server application on default the port.
	 * @throws MalformedURLException if the AppName is not a correct URL
	 * @throws BindException if the port is already in use
	 */
	public void start()
			throws RemoteException, MalformedURLException {
		this.start(DEFAULT_PORT);
	}
	
	/**
	 * Stops the running server.
	 * @throws NoSuchObjectException if server is not running
	 */
	public void stop()
			throws NoSuchObjectException {
		UnicastRemoteObject.unexportObject(this.reg, true);
	}
}
